package MyGui;

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import java.io.*;
import java.net.*;

import Engines.*;
import DistSys.*;
import Element.*;
import Element.Geom.*;

public class RelIndDlg extends MyDlgFrame implements ActionListener{
    Font      f = GuiConst.fontDefault;
    ZoneComboBox comboChoice;
    JButton   btnCompute, btnComputeAllZones;
    JLabel[]  labels;
    final int NUM_LABEL =19;
    final int MAIFI=0,SAIFI=1,SAIDI=2,CAIDI=3,ASAI=4,
              CAIFI=5,ASIFI=6,ASIDI=7,CTAIDI=8,SARFI=9,
              NUM_CUST=10, DEMAND=11, CUST_INT=12,
              CAP_COST=13,OM_COST=14,
              MOMENT_COST=15,SUST_COST=16,SAG_COST=17,TOTAL_COST=18;

    final int TMF=0, TSF=1, TOD=2, TVS=3,TIntKVA=4,TIntKVAHr=5;
    final int TKVA=6, TCust=7, TIntCust=8; //total customers, interrupted customers
    final int TCapitalCost=9, TOMCost=10;
    final int MFCost=11, SFCost=12, VSCost=13;

    public RelIndDlg(MainFrame parent, String title) {
        super(parent, title);

        labels= new JLabel[NUM_LABEL];
        for(int i=0;i<NUM_LABEL;i++){
            labels[i] = new JLabel("--");
            labels[i].setAlignmentX( JLabel.RIGHT_ALIGNMENT);
            // labels[i].setBackground(new Color(153,153,255));
            labels[i].setForeground(Color.blue);
        }

        JPanel topPanel = createTopPanel();
        JPanel generalPanel = createGeneralPanel();
        JPanel indicesPanel = createIndicesPanel();
        JPanel utilCostPanel = createUtilCostPanel();
        JPanel custCostPanel = createCustCostPanel();

        Container pane = this.getContentPane();
        pane.setLayout(gridBagLayout);

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(GAP, GAP, 0, GAP);
        c.fill = GridBagConstraints.BOTH;
        c.anchor = GridBagConstraints.WEST;

        c.gridwidth = 2; c.weightx = 1;
        c.gridx=0; c.gridy=0; pane.add(topPanel,c);

        c.gridwidth = 1; c.weighty = 1; c.insets.top = 0; c.insets.bottom = GAP;
        c.gridx=0; c.gridy=1; c.insets.right = 0; pane.add(generalPanel,c);
        c.gridx=1; c.gridy=1; c.insets.right = GAP; pane.add(indicesPanel,c);
        c.gridx=0; c.gridy=2; c.insets.right = 0; pane.add(utilCostPanel,c);
        c.gridx=1; c.gridy=2; c.insets.right = GAP; pane.add(custCostPanel,c);

        compute();

        this.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        this.setSize(570,325);
        this.setLocation(200,200);
        this.setResizable(false);
    }

    private JPanel createTopPanel(){
        JPanel p = new JPanel();
        p.setLayout( new FlowLayout( FlowLayout.LEFT));
        JLabel lblOne = new JLabel("Area:");

        comboChoice = new ZoneComboBox();

        btnCompute = new JButton("Compute");
        btnComputeAllZones = new JButton("Export Indices for All Zones");
        btnCompute.addActionListener(this);
        btnComputeAllZones.addActionListener(this);

        p.add(lblOne);
        p.add(comboChoice);
        p.add(btnCompute);
        p.add(btnComputeAllZones);
        return p;
    }

    private JPanel createGeneralPanel(){
        JPanel p = new JPanel(gridBagLayout);
        p.setBorder( new TitledBorder(" General Information "));

        JLabel lblOne = new JLabel("No. of Customers:");
        JLabel lblTwo = new JLabel("Demand(kVA):");
        JLabel lblThree=new JLabel("% of Customers");
        JLabel lblFour =new JLabel("interrupted/yr:", JLabel.RIGHT);

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(0, GAP, GAP/2, GAP);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.NORTHWEST;

        c.gridx = 0; c.gridy = 0; c.weightx = 0; p.add(lblOne, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[NUM_CUST], c);

        c.gridx = 0; c.gridy = 1; c.weightx = 0; p.add(lblTwo, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[DEMAND], c);

        c.gridx = 0; c.gridy = 2; c.weightx = 0; p.add(lblThree, c);
        c.weighty = 1; c.insets.bottom = GAP;
                     c.gridy = 3;                p.add(lblFour, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[CUST_INT], c);

        return p;
    }

    private JPanel createIndicesPanel(){
        JPanel p = new JPanel(gridBagLayout);
        p.setBorder(new TitledBorder(" Indices "));

        JLabel[] staticLabels = new JLabel[10];
        staticLabels[0]= new JLabel("MAIFI:");
        staticLabels[1]= new JLabel("SAIFI:");
        staticLabels[2]= new JLabel("SAIDI:");
        staticLabels[3]= new JLabel("CAIDI:");
        staticLabels[4]= new JLabel("ASAI :");
        staticLabels[5]= new JLabel("CAIFI:");
        staticLabels[6]= new JLabel("ASIFI:");
        staticLabels[7]= new JLabel("ASIDI:");
        staticLabels[8]= new JLabel("CTAIDI:");
        staticLabels[9]= new JLabel("SARFI:");

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(0, GAP, GAP/2, GAP);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.NORTHWEST;

        for (int i = 0; i < 5; i++) {
            if (i == 4) {
                c.weighty = 1; c.insets.bottom = GAP;
            }
            c.gridy = i;
            c.gridx = 0; c.weightx = 0; p.add(staticLabels[i], c);
            c.gridx = 1; c.weightx = 1; p.add(labels[MAIFI+i], c);
            c.gridx = 2; c.weightx = 0; p.add(staticLabels[i+5], c);
            c.gridx = 3; c.weightx = 1; p.add(labels[MAIFI+i+5], c);
        }

        return p;
    }

    private JPanel createUtilCostPanel(){
        JPanel p = new JPanel(gridBagLayout);
        p.setBorder( new TitledBorder(" Utility Costs "));

        JLabel lblOne =new JLabel("Capital Cost($):");
        JLabel lblTwo =new JLabel("OM Cost($/yr):");

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(0, GAP, GAP/2, GAP);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.NORTHWEST;

        c.gridx = 0; c.gridy = 0; c.weightx = 0; p.add(lblOne, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[CAP_COST], c);

        c.weighty = 1; c.insets.bottom = GAP;
        c.gridx = 0; c.gridy = 1; c.weightx = 0; p.add(lblTwo, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[OM_COST], c);

        return p;
    }

    private JPanel createCustCostPanel(){
        JPanel p = new JPanel(gridBagLayout);
        p.setBorder( new TitledBorder(" Customer Costs "));

        JLabel lblOne =new JLabel("Momentary Interruptions($/yr):");
        JLabel lblTwo =new JLabel("Sustained Interruptions($/yr):");
        JLabel lblThree=new JLabel("Voltage Sags($/yr):");
        JLabel lblFour =new JLabel("Total Cost($/yr):");

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(0, GAP, GAP/2, GAP);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.NORTHWEST;

        c.gridx = 0; c.gridy = 0; c.weightx = 0; p.add(lblOne, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[MOMENT_COST], c);

        c.gridx = 0; c.gridy = 1; c.weightx = 0; p.add(lblTwo, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[SUST_COST], c);

        c.gridx = 0; c.gridy = 2; c.weightx = 0; p.add(lblThree, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[SAG_COST], c);

        c.weighty = 1; c.insets.bottom = GAP;
        c.gridx = 0; c.gridy = 3; c.weightx = 0; p.add(lblFour, c);
        c.gridx = 1;              c.weightx = 1; p.add(labels[TOTAL_COST], c);

        return p;
    }

    private void compute() {
        double dZone;
        try {
            dZone = comboChoice.getSelectedZone();
        } catch(ZoneComboBox.ZoneException e) {
            JOptionPane.showMessageDialog(this,
                "'" + e.getMessage() + "' is not a valid zone.");
            return;
        }

        EngineProcessor.computeReliabilityIndices(dZone);
        double[] val = EngineProcessor.val;
        double[] indices = EngineProcessor.indices;

        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(2);
        nf.setGroupingUsed(false);

        labels[NUM_CUST].setText( nf.format(val[TCust]));
        labels[DEMAND].setText( nf.format(val[TKVA]));
        labels[CUST_INT].setText( nf.format(val[TIntCust]*100.0/val[TCust])+"%");

        labels[MAIFI].setText( nf.format( indices[MAIFI]));
        labels[SAIFI].setText( nf.format( indices[SAIFI]));
        labels[SAIDI].setText( nf.format( indices[SAIDI]));
        labels[CAIDI].setText( nf.format( indices[CAIDI]));
        labels[ASAI].setText( nf.format( indices[ASAI] ));
        labels[CAIFI].setText( nf.format( indices[CAIFI]));
        labels[ASIFI].setText( nf.format( indices[ASIFI]));
        labels[ASIDI].setText( nf.format( indices[ASIDI]));
        labels[CTAIDI].setText( nf.format( indices[CTAIDI]));
        labels[SARFI].setText( nf.format( indices[SARFI]));   //SAGS?

        nf.setMaximumFractionDigits(0);
        nf.setGroupingUsed(true);

        labels[CAP_COST].setText( nf.format( val[TCapitalCost]));
        labels[OM_COST].setText( nf.format( val[TOMCost]));
        labels[MOMENT_COST].setText( nf.format( val[MFCost]));
        labels[SUST_COST].setText( nf.format( val[SFCost]));
        labels[SAG_COST].setText( nf.format( val[VSCost]));
        labels[TOTAL_COST].setText( nf.format( val[MFCost]+ val[SFCost]+ val[VSCost]));
    }

    public void actionPerformed(ActionEvent evt){
        Object o = evt.getSource();

        if( o == btnCompute){
            compute();
        } else if( o == btnComputeAllZones ) {
            int sz = Sys.prjInfo.allZone.size();
            double dZone;
            try{
                File f = Sys.personalInfo.createTempExportFile();
                BufferedWriter bw = new BufferedWriter(new FileWriter(f));
                bw.write("\"Performance Advantange Reliability Analysis\"\n");
                bw.write("\"\"\n");
                bw.write("\"\"\n");
                bw.write("\"Zone\",\"MAIFI\",\"SAIFI\",\"SAIDI\",\"CAIDI\",\"SARFI\"\n");

                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(2);
                nf.setGroupingUsed(false);

                Zone z = null;
                for(int i=0; i< sz+1; i++){
                    if(i<sz){
                        z = (Zone)Sys.prjInfo.allZone.elementAt(i);
                        dZone = z.getZoneNumber();
                    }
                    else{ dZone = Zone.ENTIRE_SYSTEM; } //final run for system

                    EngineProcessor.computeReliabilityIndices(dZone);
                    double[] val = EngineProcessor.val;
                    double[] indices = EngineProcessor.indices;

                    if(dZone != Zone.ENTIRE_SYSTEM) {
                        bw.write("\""+z.getZoneString()+"\"");
                    } else {
                        bw.write("\"Total\"");
                    }
                    bw.write(","+nf.format(indices[MAIFI])
                            +","+nf.format(indices[SAIFI])
                            +","+nf.format(indices[SAIDI])
                            +","+nf.format(indices[CAIDI])
                            +","+nf.format(indices[SARFI])+"\n");
                  }//end of loop for zones
                  bw.close();

                  Sys.personalInfo.execExcel(f.getPath());
            }catch (IOException e){
                JOptionPane.showMessageDialog(this,
                    "Error occured when writing to PA_Export.cvs\n"+e);
                return;
            }catch(Exception e){
                JOptionPane.showMessageDialog(this, e);
                return;
            }
        }//end of btnComputeAllZones
    }
}